package com.study.kt._03coroutines

import kotlinx.coroutines.flow.*
import kotlinx.coroutines.runBlocking
import java.lang.RuntimeException

/**
 * <pre>
 *     author : slx
 *     time   : 2021/04/04
 *     desc   : Flow的完成:命令式(try、finally)、声明式(onCompletion)
 *
 *     onCompletion只会看到来自于Flow上游的异常(该操作符之前操作的异常)，但是看不到Flow下游(该操作符之后的操作)的异常
 * </pre>
 */
fun main() {
    runBlocking {
        // 命令式完成Flow
        try {
            finishFlow().collect { println(it) }
        } finally {
            println("Flow finish")
        }
        println("-------------------")
        // 声明式：onCompletion中间操作，优势在于有一个可空的Throwable参数，可用作判断Flow的收集操作是正常完成还是异常完成
        finishFlow().onCompletion { println("onCompletion") }
                .collect { println(it) }
        println("-------------------")

        exFlow().onCompletion { ex -> if (ex != null) println("因为异常退出") }
                .catch { catch -> println("捕获异常:$catch") }
                .collect { println(it) }
    }
}

private fun finishFlow(): Flow<Int> = (1..10).asFlow()
private fun exFlow(): Flow<Int> = flow {
    emit(1)
    throw RuntimeException()
}